home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / makeindex / mkind.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-04-26  |  7.4 KB  |  395 lines

  1. /*
  2.  *
  3.  * Copyright (C) 1987     Pehong Chen    (phc@renoir.berkeley.edu)
  4.  * Computer Science Division
  5.  * University of California, Berkeley
  6.  *
  7.  */
  8.  
  9. #include    "mkind.h"
  10.  
  11. int        letter_ordering = FALSE;
  12. int        compress_blanks = FALSE;
  13. int        merge_page = TRUE;
  14. int        init_page = FALSE;
  15. int        even_odd = -1;
  16. int        verbose = TRUE;
  17. int        fn_no = -1;    /* total number of files */
  18. int        idx_dot = TRUE;    /* flag which shows dot in ilg being active */
  19. int        idx_tt = 0;    /* total entry count of all files */
  20. int        idx_et = 0;    /* erroneous entry count of all files */
  21. int        idx_gt = 0;    /* good entry count of all files */
  22.  
  23. FIELD_PTR    *idx_key;
  24. FILE        *log_fp;
  25. FILE        *sty_fp;
  26. FILE        *idx_fp;
  27. FILE        *ind_fp;
  28. FILE        *ilg_fp;
  29. char        *pgm_fn;
  30. char        sty_fn[LINE_MAX];
  31. char        *idx_fn;
  32. char        ind[STRING_MAX];
  33. char        *ind_fn;
  34. char        ilg[STRING_MAX];
  35. char        *ilg_fn;
  36. char        pageno[STRING_MAX];
  37. static char    log_fn[STRING_MAX];
  38. static char    base[STRING_MAX];
  39. static int    need_version = TRUE;
  40.  
  41.  
  42. main(argc, argv)
  43.     int        argc;
  44.     char        *argv[];
  45. {
  46.     char        *fns[LONG_MAX];
  47.     char        *ap;
  48.     int        use_stdin = FALSE;
  49.     int        sty_given = FALSE;
  50.     int        ind_given = FALSE;
  51.     int        ilg_given = FALSE;
  52.     int        log_given = FALSE;
  53.  
  54.     /* determine program name */
  55.     pgm_fn = rindex(*argv, DIR_DELIM);
  56.     if (pgm_fn == NULL)
  57.         pgm_fn = *argv;
  58.     else
  59.             pgm_fn++;
  60.  
  61.     /* process command line options */
  62.     while (--argc > 0) {
  63.         if (**++argv == SW_PREFIX) {
  64.             if (*(*argv+1) == NULL)
  65.                 break;
  66.             for (ap = ++*argv; *ap != NULL; ap++)
  67.                 switch (*ap) {
  68.  
  69.                 /* use standard input */
  70.                 case 'i':
  71.                     use_stdin = TRUE;
  72.                     break;
  73.  
  74.                 /* enable letter ordering */
  75.                 case 'l':
  76.                     letter_ordering = TRUE;
  77.                     break;
  78.  
  79.                 /* disable range merge */
  80.                 case 'r':
  81.                     merge_page = FALSE;
  82.                     break;
  83.  
  84.                 /* supress progress message -- quiet mode */
  85.                 case 'q':
  86.                     verbose = FALSE;
  87.                     break;
  88.  
  89.                 /* compress blanks */
  90.                 case 'c':
  91.                     compress_blanks = TRUE;
  92.                     break;
  93.  
  94.                 /* style file */
  95.                 case 's':
  96.                     argc--;
  97.                     open_sty(*++argv);
  98.                     sty_given = TRUE;
  99.                     break;
  100.  
  101.                 /* output index file name */
  102.                 case 'o':
  103.                     argc--;
  104.                     ind_fn = *++argv;
  105.                     ind_given = TRUE;
  106.                     break;
  107.  
  108.                 /* transcript file name */
  109.                 case 't':
  110.                     argc--;
  111.                     ilg_fn = *++argv;
  112.                     ilg_given = TRUE;
  113.                     break;
  114.  
  115.                 /* initial page */
  116.                 case 'p':
  117.                     argc--;
  118.                     strcpy(pageno, *++argv);
  119.                     init_page = TRUE;
  120.                     if (STREQ(pageno, EVEN)) {
  121.                         log_given = TRUE;
  122.                         even_odd = 2;
  123.                     } else if (STREQ(pageno, ODD)) {
  124.                           log_given = TRUE;
  125.                         even_odd = 1;
  126.                     } else if (STREQ(pageno, ANY)) {
  127.                           log_given = TRUE;
  128.                         even_odd = 0;
  129.                     }
  130.                     break;
  131.  
  132.                 /* bad option */
  133.                        default:
  134.                     FATAL("Unknown option -%c.\n", *ap);
  135.                     break;
  136.                 }
  137.         } else {
  138.             if (fn_no < LONG_MAX) {
  139.                     check_idx(*argv, FALSE);
  140.                 fns[++fn_no] = *argv;
  141.             } else {
  142.                 FATAL("Too many input files (max %d).\n", LONG_MAX);
  143.             }
  144.         }
  145.     }
  146.  
  147.     process_idx(fns, use_stdin, sty_given, ind_given, ilg_given, log_given);
  148.     idx_gt = idx_tt - idx_et;
  149.     if (idx_gt > 0) {
  150.         prepare_idx();
  151.         sort_idx();
  152.         gen_ind();
  153.         MESSAGE("Output written in %s.\n", ind_fn);
  154.     } else
  155.         MESSAGE("Nothing written in %s.\n", ind_fn);
  156.  
  157.     MESSAGE("Transcript written in %s.\n", ilg_fn);
  158.     CLOSE(ind_fp);
  159.     CLOSE(ilg_fp);
  160.     EXIT(0);
  161.  
  162.     return(0);            /* never executed--avoids complaints */
  163.                     /* about no return value */
  164. }
  165.  
  166.  
  167. static void
  168. prepare_idx()
  169. {
  170.     NODE_PTR    ptr = head;
  171.     int        i = 0;
  172.  
  173.     if ((idx_key = (FIELD_PTR *) calloc(idx_gt, sizeof(FIELD_PTR))) == NULL) {
  174.         FATAL("Not enough core...abort.\n", "");
  175.     }
  176.     for (i = 0; i < idx_gt; i++) {
  177.         idx_key[i] = &(ptr->data);
  178.         ptr = ptr->next;
  179.     }
  180. }
  181.  
  182.  
  183. static void
  184. process_idx(fn, use_stdin, sty_given, ind_given, ilg_given, log_given)
  185.     char        *fn[];
  186.     int        use_stdin;
  187.     int        sty_given;
  188.     int        ind_given;
  189.     int        ilg_given;
  190.     int        log_given;
  191. {
  192.     int        i;
  193.  
  194.     if (fn_no == -1)
  195.             /* use stdin if no input files specified */
  196.         use_stdin = TRUE;
  197.     else {
  198.         check_all(fn[0], ind_given, ilg_given, log_given);
  199.         PUT_VERSION;
  200.         if (sty_given)
  201.             scan_sty();
  202.         scan_idx();
  203.         ind_given = TRUE;
  204.         ilg_given = TRUE;
  205.         for (i = 1; i <= fn_no; i++) {
  206.             check_idx(fn[i], TRUE);
  207.             scan_idx();
  208.         }
  209.     }
  210.  
  211.     if (use_stdin) {
  212.         idx_fn = "stdin";
  213.         idx_fp = stdin;
  214.  
  215.         if (ind_given) {
  216.             if (ind_fp == NULL)
  217.                 ind_fp = OPEN_OUT(ind_fn);
  218.         } else {
  219.             ind_fn = "stdout";
  220.             ind_fp = stdout;
  221.         }
  222.  
  223.         if (ilg_given) {
  224.             if (ilg_fp == NULL)
  225.                 ilg_fp = OPEN_OUT(ilg_fn);
  226.         } else {
  227.             ilg_fn = "stderr";
  228.             ilg_fp = stderr;
  229.         }
  230.  
  231.         if (need_version) {
  232.             PUT_VERSION;
  233.         }
  234.         if ((fn_no == -1) && (sty_given))
  235.                 scan_sty();
  236.         scan_idx();
  237.         fn_no++;
  238.     }
  239.  
  240.     ALL_DONE;
  241. }
  242.  
  243.  
  244. static void
  245. check_idx(fn, open_fn)
  246.     char        *fn;
  247.     int        open_fn;
  248. {
  249.     char        *ptr = fn;
  250.     char        *ext;
  251.     int        with_ext = FALSE;
  252.     int        i = 0;
  253.  
  254.     ext = rindex(fn, EXT_DELIM);
  255.     if ((ext != NULL) && (ext != fn) && (*(ext+1) != DIR_DELIM)) {
  256.         with_ext = TRUE;
  257.         while ((ptr != ext) && (i < STRING_MAX))
  258.             base[i++] = *ptr++;
  259.     } else
  260.         while ((*ptr != NULL) && (i < STRING_MAX))
  261.             base[i++] = *ptr++;
  262.  
  263.     if (i < STRING_MAX)
  264.         base[i] = NULL;
  265.     else
  266.         FATAL2("Index file name %s too long (max %d).\n",
  267.                base, STRING_MAX);
  268.  
  269.     idx_fn = fn;
  270.     if (((open_fn) && ((idx_fp = OPEN_IN(idx_fn)) == NULL)) ||
  271.         ((! open_fn) && (access(idx_fn, R_OK) != 0)))
  272.         if (with_ext) {
  273.             FATAL("Input index file %s not found.\n", idx_fn);
  274.         } else {
  275.             if ((idx_fn = (char *) malloc(STRING_MAX)) == NULL)
  276.                 FATAL("Not enough core...abort.\n", "");
  277.             sprintf(idx_fn, "%s%s", base, INDEX_IDX);
  278.             if (((open_fn) && ((idx_fp = OPEN_IN(idx_fn)) == NULL)) ||
  279.                 ((! open_fn) && (access(idx_fn, R_OK) != 0))) {
  280.                 FATAL2("Couldn't find input index file %s nor %s.\n", base, idx_fn);
  281.             }
  282.         }
  283. }
  284.  
  285.  
  286. static void
  287. check_all(fn, ind_given, ilg_given, log_given)
  288.     char        *fn;
  289.     int        ind_given;
  290.     int        ilg_given;
  291.     int        log_given;
  292. {
  293.     check_idx(fn, TRUE);
  294.  
  295.     if (! ind_given) {
  296.         sprintf(ind, "%s%s", base, INDEX_IND);
  297.         ind_fn = ind;
  298.     }
  299.     ind_fp = OPEN_OUT(ind_fn);
  300.  
  301.     if (! ilg_given) {
  302.         sprintf(ilg, "%s%s", base, INDEX_ILG);
  303.         ilg_fn = ilg;
  304.     }
  305.     ilg_fp = OPEN_OUT(ilg_fn);
  306.  
  307.     if (log_given) {
  308.         sprintf(log_fn, "%s%s", base, INDEX_LOG);
  309.         if ((log_fp = OPEN_IN(log_fn)) == NULL) {
  310.             FATAL("Source log file %s not found\n", log_fn);
  311.         } else
  312.             find_pageno();
  313.     }
  314. }
  315.  
  316.  
  317. static void
  318. find_pageno()
  319. {
  320.     int        i = 0;
  321.     int        p, c;
  322.  
  323.     fseek(log_fp, -1L, 2);
  324.     p = GET_CHAR(log_fp);
  325.     fseek(log_fp, -2L, 1);
  326.     do {
  327.         c = p;
  328.         p = GET_CHAR(log_fp);
  329.     } while (! (((p == LSQ) && isdigit(c)) || (fseek(log_fp, -2L, 1) != 0)));
  330.     if (p == LSQ) {
  331.         while ((c = GET_CHAR(log_fp)) == SPC);
  332.         do {
  333.             pageno[i++] = (char)c;
  334.             c = GET_CHAR(log_fp);
  335.         } while (isdigit(c));
  336.         pageno[i] = NULL;
  337.     } else {
  338.         fprintf(ilg_fp, "Couldn't find any page number in %s...ignored\n", log_fn);
  339.         init_page = FALSE;
  340.     }
  341. }
  342.  
  343. static void
  344. open_sty(fn)
  345.     char        *fn;
  346. {
  347.     char        *path;
  348.     char        *ptr;
  349.     int        i;
  350.     int        len;
  351.  
  352.     if ((path = getenv(STYLE_PATH)) == NULL) {
  353.         /* style input path not defined */
  354.         strcpy(sty_fn, fn);
  355.         sty_fp = OPEN_IN(sty_fn);
  356.     } else {
  357.         len = LONG_MAX - strlen(fn) - 1;
  358.         while (*path != NULL) {
  359.             ptr = index(path, ENV_SEPAR);
  360.             i = 0;
  361.             while ((path != ptr) && (i < len))
  362.                 sty_fn[i++] = *path++;
  363.             if (i == len) {
  364.                 FATAL2("Path %s too long (max %d).\n",
  365.                        sty_fn, LONG_MAX);
  366.             } else {
  367.                 sty_fn[i++] = DIR_DELIM;
  368.                 sty_fn[i] = NULL;
  369.                 strcat(sty_fn, fn);
  370.                 if ((sty_fp = OPEN_IN(sty_fn)) == NULL)
  371.                     path++;
  372.                 else
  373.                     break;
  374.             }
  375.         }
  376.     }
  377.  
  378.     if (sty_fp == NULL)
  379.         FATAL("Index style file %s not found\n", fn);
  380. }
  381.  
  382.  
  383. int
  384. strtoint(str)
  385.     char        *str;
  386. {
  387.     int        val = 0;
  388.  
  389.     while (*str != NULL) {
  390.         val = 10*val + *str - 48;
  391.         str++;
  392.     }
  393.     return (val);
  394. }
  395.